﻿unit SmOrderDtlModel;

interface

uses
  FastMM4,
  FastMove,
  System.SysUtils,
  System.Classes,
  System.Types,
  Winapi.Windows,
  Data.DB,
  Data.Win.ADODB,
  Datasnap.DBClient,
  Datasnap.Provider,
  {$IFDEF UNICODE}
  AnsiStrings,
  {$ENDIF }
  QBParcel,
  DllSpread,
  Generics.Collections,
  DateUtils,
  QJson,
  UserConnection,
  DBAccessor,
  DllPlugin,
  StrUtils,
  SK0001Comm;

type

  TSmOrderDtlModel = class(TObject)
  public 
    const cModuleKey='SmOrderDtl'; 
    const cTblName ='sm_order_dtl';
    const cBaseView = 'view_sm_order_dtl';
    const cObjNameKey='ObjName';
    const cObjGUIDKey='ObjGUID';
    const cObjItemsKey='Items';
    const cCdsModelKey='CdsModel';
    
    class function GetCountSQL(const iCondition:string; const dLoadMode:eDBLoadMode=eDBLoadMode.dblmTable):string;
    class function GetQuerySQL(const iCondition:string; const dOrderBy:string=''; const dLoadMode:eDBLoadMode=eDBLoadMode.dblmTable):string;
    class function GetPageQuerySQL(const iPageNo,iPageSize:Integer; const iCondition,iOrderBy:string; const dLoadMode:eDBLoadMode=eDBLoadMode.dblmTable):string;

    const cOrderPkKey='order_pk';
    const cOrderIdKey='order_id';
    const cOrderSortNoKey='order_sort_no';
    const cItemNoKey='item_no';
    const cItemNameKey='item_name';
    const cItemSpecKey='item_spec';
    const cPackageTypeIdKey='package_type_id';
    const cRanksIdKey='ranks_id';
    const cMsunitIdKey='msunit_id';
    const cOrderDtlQtyKey='order_dtl_qty';
    const cOrderDtlPriceKey='order_dtl_price';
    const cOrderDtlSendQtyKey='order_dtl_send_qty';
    const cOrderDtlBackQtyKey='order_dtl_back_qty';
    const cOrderDtlAmountKey='order_dtl_amount';
    const cOrderDtlSettlementAmountKey='order_dtl_settlement_amount';
    const cOrderDtlRemarkKey='order_dtl_remark';
  end;
  
  TSmOrderDtl = class(TObject)
  private    
    fOrderPk:string;
    fOrderId:string;
    fOrderSortNo:Integer;
    fItemNo:string;
    fItemName:string;
    fItemSpec:string;
    fPackageTypeId:string;
    fRanksId:string;
    fMsunitId:string;
    fOrderDtlQty:Real;
    fOrderDtlPrice:Real;
    fOrderDtlSendQty:Real;
    fOrderDtlBackQty:Real;
    fOrderDtlAmount:Real;
    fOrderDtlSettlementAmount:Real;
    fOrderDtlRemark:string;
    
  protected
    fObjGUID:string;
    fInitDate:TDateTime;
    fCdsModel:TClientDataSet;
    function ObjectToCDS(const iCds:TClientDataSet; out oError:string):Boolean;
    
  public
    constructor Create();overload;
    destructor Destroy;override;
    
    procedure ResetObject;
    
    function LoadFromCDS(const iCds:TClientDataSet; out oError:string):Boolean;
    function SaveToCDS(const iCds:TClientDataSet; out oError:string):Boolean;
    function LoadFromStr(const iJsonStr:string; out oError:string):Boolean;
    function SaveToStr():string;
    
    property ObjGUID:string read fObjGUID;
    property OrderPk:string read fOrderPk write fOrderPk;
    property OrderId:string read fOrderId write fOrderId;
    property OrderSortNo:Integer read fOrderSortNo write fOrderSortNo;
    property ItemNo:string read fItemNo write fItemNo;
    property ItemName:string read fItemName write fItemName;
    property ItemSpec:string read fItemSpec write fItemSpec;
    property PackageTypeId:string read fPackageTypeId write fPackageTypeId;
    property RanksId:string read fRanksId write fRanksId;
    property MsunitId:string read fMsunitId write fMsunitId;
    property OrderDtlQty:Real read fOrderDtlQty write fOrderDtlQty;
    property OrderDtlPrice:Real read fOrderDtlPrice write fOrderDtlPrice;
    property OrderDtlSendQty:Real read fOrderDtlSendQty write fOrderDtlSendQty;
    property OrderDtlBackQty:Real read fOrderDtlBackQty write fOrderDtlBackQty;
    property OrderDtlAmount:Real read fOrderDtlAmount write fOrderDtlAmount;
    property OrderDtlSettlementAmount:Real read fOrderDtlSettlementAmount write fOrderDtlSettlementAmount;
    property OrderDtlRemark:string read fOrderDtlRemark write fOrderDtlRemark;
  end;

  TSmOrderDtlList = class(TDictionary<string,TSmOrderDtl>)
  private
    fCdsModel:TClientDataSet;
    fSortKeys:TStrings;
    
  public
    constructor Create();overload;
    destructor Destroy;override;
    
    procedure ResetObject;
    
    function LoadFromCDS(const iCds:TClientDataSet; out oError:string):Boolean;
    function SaveToCDS(const iCds:TClientDataSet; out oError:string):Boolean;
    function LoadFromStr(const iJsonStr:string; out oError:string):Boolean;
    function SaveToStr():string;
    
    function FindByKey(const iKey:string):TSmOrderDtl;
    function IsExist(iKey:string):Boolean;
    function Add(const iItem:TSmOrderDtl):string;
    function Delete(const iKey:string):Boolean;
    function Remove(const iKey:string):TSmOrderDtl;
    procedure Clear;
    
    property SortKeys:TStrings read fSortKeys write fSortKeys;
  end;

implementation

class function TSmOrderDtlModel.GetCountSQL(const iCondition:string; const dLoadMode:eDBLoadMode):string;
var
  ReadName:string;
begin
  case dLoadMode of
    dblmNone: ReadName:=TSmOrderDtlModel.cTblName;
    dblmTable: ReadName:=TSmOrderDtlModel.cTblName;
    dblmView: ReadName:=TSmOrderDtlModel.cBaseView;
  end;
  
  if SameStr(Trim(iCondition),EmptyStr) then
  begin
    Result:=Format(string('SELECT COUNT(*) AS ''COUNT'' FROM %s;'),[ReadName]);
  end else begin
    Result:=Format(string('SELECT COUNT(*) AS ''COUNT'' FROM %s WHERE %s;'),[ReadName,iCondition]);
  end;
end;

class function TSmOrderDtlModel.GetQuerySQL(const iCondition:string; const dOrderBy:string; const dLoadMode:eDBLoadMode):string;
var
  ReadName:string;
begin
  case dLoadMode of
    dblmNone: ReadName:=TSmOrderDtlModel.cTblName;
    dblmTable: ReadName:=TSmOrderDtlModel.cTblName;
    dblmView: ReadName:=TSmOrderDtlModel.cBaseView;
  end;
  
  if SameStr(Trim(iCondition),EmptyStr) then
  begin
    Result:=Format(string('SELECT * FROM %s %s;'),[ReadName,
                                                 IfThen(SameStr(dOrderBy,EmptyStr),'','ORDER BY '+dOrderBy)]);
  end else begin
    Result:=Format(string('SELECT * FROM %s WHERE %s %s;'),[ReadName,iCondition,
                                                            IfThen(SameStr(dOrderBy,EmptyStr),'','ORDER BY '+dOrderBy)]);
  end;
end;

class function TSmOrderDtlModel.GetPageQuerySQL(const iPageNo,iPageSize:Integer; const iCondition,iOrderBy:string; const dLoadMode:eDBLoadMode):string;
var
  ReadName:string;
begin
  case dLoadMode of
    dblmNone: ReadName:=TSmOrderDtlModel.cTblName;
    dblmTable: ReadName:=TSmOrderDtlModel.cTblName;
    dblmView: ReadName:=TSmOrderDtlModel.cBaseView;
  end;
  
  if SameStr(Trim(iCondition),EmptyStr) then
  begin      
    Result:=Format(string('SELECT * FROM %s'),[ReadName]);
  end else begin
    Result:=Format(string('SELECT * FROM %s WHERE %s'),[ReadName,iCondition]);
  end;
  Result:=Format(string('SELECT TOP %d * FROM (SELECT row_number() OVER(ORDER BY %s) AS _row_no_,* FROM (%s) AS A) AS B WHERE _row_no_>%d ORDER BY _row_no_'),
                  [iPageSize,
                  IfThen(SameStr(Trim(iOrderBy),EmptyStr),'',iOrderBy),
                  Result,
                  (iPageNo-1)*iPageSize]);
end;

constructor TSmOrderDtl.Create();
begin
  inherited Create;
  fInitDate:=EncodeDateTime( 1899, 12, 30, 0, 0, 0, 0 );
  fCdsModel:=TClientDataSet.Create(nil);
  ResetObject;
end;

destructor TSmOrderDtl.Destroy;
begin
  FreeAndNil(fCdsModel);
  inherited Destroy;
end;

procedure TSmOrderDtl.ResetObject;
begin
  fObjGUID:=TSK0001Comm.GetGUID;
  fOrderPk:=EmptyStr;
  fOrderId:=EmptyStr;
  fOrderSortNo:=-1;
  fItemNo:=EmptyStr;
  fItemName:=EmptyStr;
  fItemSpec:=EmptyStr;
  fPackageTypeId:=EmptyStr;
  fRanksId:=EmptyStr;
  fMsunitId:=EmptyStr;
  fOrderDtlQty:=-1;
  fOrderDtlPrice:=-1;
  fOrderDtlSendQty:=-1;
  fOrderDtlBackQty:=-1;
  fOrderDtlAmount:=-1;
  fOrderDtlSettlementAmount:=-1;
  fOrderDtlRemark:=EmptyStr;
end;

function TSmOrderDtl.LoadFromCDS(const iCds:TClientDataSet; out oError:string):Boolean;
begin
  if (iCds<>nil) then
  begin
    ResetObject;
    if (iCds.FindField(TSmOrderDtlModel.cOrderPkKey)<>nil) then
    begin
      fOrderPk:=iCds.FieldByName(TSmOrderDtlModel.cOrderPkKey).AsString;     
      fObjGUID:=TSK0001Comm.SetObjGUID(fOrderPk);
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderPkKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderIdKey)<>nil) then
    begin
      fOrderId:=iCds.FieldByName(TSmOrderDtlModel.cOrderIdKey).AsString;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderIdKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderSortNoKey)<>nil) then
    begin
      fOrderSortNo:=iCds.FieldByName(TSmOrderDtlModel.cOrderSortNoKey).AsInteger;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderSortNoKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cItemNoKey)<>nil) then
    begin
      fItemNo:=iCds.FieldByName(TSmOrderDtlModel.cItemNoKey).AsString;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cItemNoKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cItemNameKey)<>nil) then
    begin
      fItemName:=iCds.FieldByName(TSmOrderDtlModel.cItemNameKey).AsString;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cItemNameKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cItemSpecKey)<>nil) then
    begin
      fItemSpec:=iCds.FieldByName(TSmOrderDtlModel.cItemSpecKey).AsString;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cItemSpecKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cPackageTypeIdKey)<>nil) then
    begin
      fPackageTypeId:=iCds.FieldByName(TSmOrderDtlModel.cPackageTypeIdKey).AsString;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cPackageTypeIdKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cRanksIdKey)<>nil) then
    begin
      fRanksId:=iCds.FieldByName(TSmOrderDtlModel.cRanksIdKey).AsString;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cRanksIdKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cMsunitIdKey)<>nil) then
    begin
      fMsunitId:=iCds.FieldByName(TSmOrderDtlModel.cMsunitIdKey).AsString;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cMsunitIdKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderDtlQtyKey)<>nil) then
    begin
      fOrderDtlQty:=iCds.FieldByName(TSmOrderDtlModel.cOrderDtlQtyKey).AsFloat;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderDtlQtyKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderDtlPriceKey)<>nil) then
    begin
      fOrderDtlPrice:=iCds.FieldByName(TSmOrderDtlModel.cOrderDtlPriceKey).AsFloat;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderDtlPriceKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderDtlSendQtyKey)<>nil) then
    begin
      fOrderDtlSendQty:=iCds.FieldByName(TSmOrderDtlModel.cOrderDtlSendQtyKey).AsFloat;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderDtlSendQtyKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderDtlBackQtyKey)<>nil) then
    begin
      fOrderDtlBackQty:=iCds.FieldByName(TSmOrderDtlModel.cOrderDtlBackQtyKey).AsFloat;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderDtlBackQtyKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderDtlAmountKey)<>nil) then
    begin
      fOrderDtlAmount:=iCds.FieldByName(TSmOrderDtlModel.cOrderDtlAmountKey).AsFloat;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderDtlAmountKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderDtlSettlementAmountKey)<>nil) then
    begin
      fOrderDtlSettlementAmount:=iCds.FieldByName(TSmOrderDtlModel.cOrderDtlSettlementAmountKey).AsFloat;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderDtlSettlementAmountKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderDtlRemarkKey)<>nil) then
    begin
      fOrderDtlRemark:=iCds.FieldByName(TSmOrderDtlModel.cOrderDtlRemarkKey).AsString;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderDtlRemarkKey]);
      Result:=False;
      Exit;
    end;
  end else begin
    oError:=Format(string('调用%s.LoadFromCDS函数参数错误!错误内容:传入的Cds对象为空!'),[Self.ClassName]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSmOrderDtl.ObjectToCDS(const iCds:TClientDataSet; out oError:string):Boolean;
begin
  if (iCds<>nil) then
  begin
    if (iCds.FindField(TSmOrderDtlModel.cOrderPkKey)<>nil) then
    begin
      iCds.FieldByName(TSmOrderDtlModel.cOrderPkKey).AsString:=fOrderPk;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderPkKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderIdKey)<>nil) then
    begin
      iCds.FieldByName(TSmOrderDtlModel.cOrderIdKey).AsString:=fOrderId;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderIdKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderSortNoKey)<>nil) then
    begin
      iCds.FieldByName(TSmOrderDtlModel.cOrderSortNoKey).AsInteger:=fOrderSortNo;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderSortNoKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cItemNoKey)<>nil) then
    begin
      iCds.FieldByName(TSmOrderDtlModel.cItemNoKey).AsString:=fItemNo;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cItemNoKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cItemNameKey)<>nil) then
    begin
      iCds.FieldByName(TSmOrderDtlModel.cItemNameKey).AsString:=fItemName;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cItemNameKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cItemSpecKey)<>nil) then
    begin
      iCds.FieldByName(TSmOrderDtlModel.cItemSpecKey).AsString:=fItemSpec;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cItemSpecKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cPackageTypeIdKey)<>nil) then
    begin
      iCds.FieldByName(TSmOrderDtlModel.cPackageTypeIdKey).AsString:=fPackageTypeId;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cPackageTypeIdKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cRanksIdKey)<>nil) then
    begin
      iCds.FieldByName(TSmOrderDtlModel.cRanksIdKey).AsString:=fRanksId;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cRanksIdKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cMsunitIdKey)<>nil) then
    begin
      iCds.FieldByName(TSmOrderDtlModel.cMsunitIdKey).AsString:=fMsunitId;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cMsunitIdKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderDtlQtyKey)<>nil) then
    begin
      iCds.FieldByName(TSmOrderDtlModel.cOrderDtlQtyKey).AsFloat:=fOrderDtlQty;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderDtlQtyKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderDtlPriceKey)<>nil) then
    begin
      iCds.FieldByName(TSmOrderDtlModel.cOrderDtlPriceKey).AsFloat:=fOrderDtlPrice;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderDtlPriceKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderDtlSendQtyKey)<>nil) then
    begin
      iCds.FieldByName(TSmOrderDtlModel.cOrderDtlSendQtyKey).AsFloat:=fOrderDtlSendQty;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderDtlSendQtyKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderDtlBackQtyKey)<>nil) then
    begin
      iCds.FieldByName(TSmOrderDtlModel.cOrderDtlBackQtyKey).AsFloat:=fOrderDtlBackQty;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderDtlBackQtyKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderDtlAmountKey)<>nil) then
    begin
      iCds.FieldByName(TSmOrderDtlModel.cOrderDtlAmountKey).AsFloat:=fOrderDtlAmount;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderDtlAmountKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderDtlSettlementAmountKey)<>nil) then
    begin
      iCds.FieldByName(TSmOrderDtlModel.cOrderDtlSettlementAmountKey).AsFloat:=fOrderDtlSettlementAmount;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderDtlSettlementAmountKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSmOrderDtlModel.cOrderDtlRemarkKey)<>nil) then
    begin
      iCds.FieldByName(TSmOrderDtlModel.cOrderDtlRemarkKey).AsString:=fOrderDtlRemark;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSmOrderDtlModel.cOrderDtlRemarkKey]);
      Result:=False;
      Exit;
    end;
  end else begin
    oError:=Format(string('调用%s.ObjectToCDS函数参数错误!错误内容:传入的Cds对象为空!'),[Self.ClassName]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSmOrderDtl.SaveToCDS(const iCds:TClientDataSet; out oError:string):Boolean;
begin
  if (iCds<>nil) then
  begin
    iCds.Append;
    if ObjectToCDS(iCds,oError) then
    begin
      iCds.Post;
    end else begin
      Result:=False;
      Exit;
    end;
  end else begin
    oError:=Format(string('调用%s.SaveToCDS函数参数错误!错误内容:传入的Cds对象为空!'),[Self.ClassName]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSmOrderDtl.LoadFromStr(const iJsonStr:string; out oError:string):Boolean;
var
  Json:TQJson;
  MemStream:TMemoryStream;
begin
  Json:=TQJson.Create;
  MemStream:=TMemoryStream.Create;
  try
    if Json.TryParse(iJsonStr) then
    begin
      if (Json.ItemByName(TSmOrderDtlModel.cObjNameKey)<>nil) then
      begin
        if (Self.ClassName<>Json.ItemByName(TSmOrderDtlModel.cObjNameKey).AsString) then
        begin
          //oError:=Format(string('调用%s.LoadFromStr函数！错误内容:对象类名不匹配.'),[Self.ClassName]);
          //Result:=False;
          //Exit;
        end;
      end else begin
        oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性节点.'),[Self.ClassName,TSmOrderDtlModel.cObjNameKey]);
        Result:=False;
        Exit;
      end;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:解析Json失败.iJsonStr:%s'),[Self.ClassName,iJsonStr]);
      Result:=False;
      Exit;
    end;
    ResetObject;
      
    if (Json.ItemByName(TSmOrderDtlModel.cCdsModelKey)<>nil) and 
      not SameStr(Trim(Json.ItemByName(TSmOrderDtlModel.cCdsModelKey).AsString),EmptyStr) then
    begin
      TSK0001Comm.Base64StrToMemStream(AnsiString(Json.ItemByName(TSmOrderDtlModel.cCdsModelKey).AsString),MemStream);
      if MemStream.Size>0 then
      begin
        fCdsModel.LoadFromStream(MemStream);
      end;
    end;
    
    if (Json.ItemByName(TSmOrderDtlModel.cObjGUIDKey)<>nil) and 
      not SameStr(Trim(Json.ItemByName(TSmOrderDtlModel.cObjGUIDKey).AsString),EmptyStr) then
    begin
      fObjGUID:=Json.ItemByName(TSmOrderDtlModel.cObjGUIDKey).AsString;
    end;
    
    if Json.ItemByName('OrderPk')<>nil then
    begin
      fOrderPk:=Json.ItemByName('OrderPk').AsString;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'OrderPk']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('OrderId')<>nil then
    begin
      fOrderId:=Json.ItemByName('OrderId').AsString;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'OrderId']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('OrderSortNo')<>nil then
    begin
      fOrderSortNo:=Json.ItemByName('OrderSortNo').AsInteger;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'OrderSortNo']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('ItemNo')<>nil then
    begin
      fItemNo:=Json.ItemByName('ItemNo').AsString;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'ItemNo']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('ItemName')<>nil then
    begin
      fItemName:=Json.ItemByName('ItemName').AsString;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'ItemName']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('ItemSpec')<>nil then
    begin
      fItemSpec:=Json.ItemByName('ItemSpec').AsString;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'ItemSpec']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('PackageTypeId')<>nil then
    begin
      fPackageTypeId:=Json.ItemByName('PackageTypeId').AsString;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'PackageTypeId']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('RanksId')<>nil then
    begin
      fRanksId:=Json.ItemByName('RanksId').AsString;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'RanksId']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('MsunitId')<>nil then
    begin
      fMsunitId:=Json.ItemByName('MsunitId').AsString;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'MsunitId']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('OrderDtlQty')<>nil then
    begin
      fOrderDtlQty:=Json.ItemByName('OrderDtlQty').AsFloat;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'OrderDtlQty']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('OrderDtlPrice')<>nil then
    begin
      fOrderDtlPrice:=Json.ItemByName('OrderDtlPrice').AsFloat;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'OrderDtlPrice']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('OrderDtlSendQty')<>nil then
    begin
      fOrderDtlSendQty:=Json.ItemByName('OrderDtlSendQty').AsFloat;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'OrderDtlSendQty']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('OrderDtlBackQty')<>nil then
    begin
      fOrderDtlBackQty:=Json.ItemByName('OrderDtlBackQty').AsFloat;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'OrderDtlBackQty']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('OrderDtlAmount')<>nil then
    begin
      fOrderDtlAmount:=Json.ItemByName('OrderDtlAmount').AsFloat;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'OrderDtlAmount']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('OrderDtlSettlementAmount')<>nil then
    begin
      fOrderDtlSettlementAmount:=Json.ItemByName('OrderDtlSettlementAmount').AsFloat;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'OrderDtlSettlementAmount']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('OrderDtlRemark')<>nil then
    begin
      fOrderDtlRemark:=Json.ItemByName('OrderDtlRemark').AsString;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'OrderDtlRemark']);
      Result:=False;
      Exit;  
    end;
    
  finally
    Json.Free;
    MemStream.Free;
  end;
  Result:=True;
end;

function TSmOrderDtl.SaveToStr():string;
var
  Json:TQJson;
  MemStream:TMemoryStream;
begin
  Result:=EmptyStr;  
  Json:=TQJson.Create;
  MemStream:=TMemoryStream.Create; 
  try
    Json.Add('ModuleKey').AsString:=TSmOrderDtlModel.cModuleKey;
    Json.Add(TSmOrderDtlModel.cObjNameKey).AsString:=Self.ClassName;
    
    fCdsModel.SaveToStream(MemStream);
    Json.Add(TSmOrderDtlModel.cCdsModelKey).AsString:=string(TSK0001Comm.MemStreamToBase64Str(MemStream));
    
    Json.Add(TSmOrderDtlModel.cObjGUIDKey).AsString:=fObjGUID;
    Json.Add('OrderPk').AsString:=fOrderPk;
    Json.Add('OrderId').AsString:=fOrderId;
    Json.Add('OrderSortNo').AsInteger:=fOrderSortNo;
    Json.Add('ItemNo').AsString:=fItemNo;
    Json.Add('ItemName').AsString:=fItemName;
    Json.Add('ItemSpec').AsString:=fItemSpec;
    Json.Add('PackageTypeId').AsString:=fPackageTypeId;
    Json.Add('RanksId').AsString:=fRanksId;
    Json.Add('MsunitId').AsString:=fMsunitId;
    Json.Add('OrderDtlQty').AsFloat:=fOrderDtlQty;
    Json.Add('OrderDtlPrice').AsFloat:=fOrderDtlPrice;
    Json.Add('OrderDtlSendQty').AsFloat:=fOrderDtlSendQty;
    Json.Add('OrderDtlBackQty').AsFloat:=fOrderDtlBackQty;
    Json.Add('OrderDtlAmount').AsFloat:=fOrderDtlAmount;
    Json.Add('OrderDtlSettlementAmount').AsFloat:=fOrderDtlSettlementAmount;
    Json.Add('OrderDtlRemark').AsString:=fOrderDtlRemark;
    Result:=Json.AsString;
  finally
    Json.Free;
    MemStream.Free;
  end;
end;

constructor TSmOrderDtlList.Create();
begin
  inherited Create;
  fCdsModel:=TClientDataSet.Create(nil);
  fSortKeys:=TStringList.Create;
  ResetObject;
end;

destructor TSmOrderDtlList.Destroy;
begin
  FreeAndNil(fCdsModel);
  Clear;
  FreeAndNil(fSortKeys);
  inherited Destroy;
end;

procedure TSmOrderDtlList.ResetObject;
begin
  Clear;
end;

function TSmOrderDtlList.LoadFromCDS(const iCds:TClientDataSet; out oError:string):Boolean;
var
  Item:TSmOrderDtl;
begin
  ResetObject;
  if iCds<>nil then
  begin
    iCds.First;
    while not iCds.Eof do
    begin
      Item:=TSmOrderDtl.Create;
      if Item.LoadFromCDS(iCds,oError) then
      begin
        if Add(Item)=EmptyStr then
        begin
          Item.Free;
          Result:=False;
          Exit;
        end;
      end else begin
        Result:=False;
        Exit;
      end;
      iCds.Next;
    end;
  end else begin
    oError:=Format(string('调用%s.LoadFromCDS函数参数错误! 错误内容传入的数据集为空!'),[Self.ClassName]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSmOrderDtlList.SaveToCDS(const iCds:TClientDataSet; out oError:string):Boolean;
var
  Key:string;
begin
  if (iCds<>nil) then
  begin
  for Key in fSortKeys do
  begin
    iCds.Append;
    if Items[Key].ObjectToCDS(iCds,oError) then
    begin
      iCds.Post;
    end else begin
      Result:=False;
      Exit;
    end;
  end;
  end else begin
    oError:=Format(string('调用%s.SaveToCDS函数参数错误! 错误内容:传入的数据集为空!'),[Self.ClassName]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSmOrderDtlList.LoadFromStr(const iJsonStr:string; out oError:string):Boolean;
var
  Json,ItemJson,ArrayJson:TQJson;
  Item:TSmOrderDtl;
  MemStream:TMemoryStream;
begin
  Json:=TQJson.Create;
  MemStream:=TMemoryStream.Create;
  try
    if Json.TryParse(iJsonStr) then
    begin
      if (Json.ItemByName(TSmOrderDtlModel.cObjNameKey)<>nil) then
      begin
        if (Self.ClassName<>Json.ItemByName(TSmOrderDtlModel.cObjNameKey).AsString) then
        begin
          //oError:=Format(string('调用%s.LoadFromStr函数参数错误! 错误内容:对象类名不匹配.'),[Self.ClassName]);
          //Result:=False;
          //Exit;
        end;
      end else begin
        oError:=Format(string('调用%s.LoadFromStr函数参数错误! 错误内容:缺少%s属性节点.'),[Self.ClassName,TSmOrderDtlModel.cObjNameKey]);
        Result:=False;
        Exit;
      end;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数参数错误! 错误内容:解析Json失败.iJsonStr:%s'),[Self.ClassName,iJsonStr]);
      Result:=False;
      Exit;
    end;
    if (Json.ItemByName(TSmOrderDtlModel.cObjItemsKey)<>nil) and
      (Json.ItemByName(TSmOrderDtlModel.cObjItemsKey).IsArray) then
    begin
      ResetObject;
      if Json.ItemByName(TSmOrderDtlModel.cCdsModelKey)<>nil then
      begin
        TSK0001Comm.Base64StrToMemStream(AnsiString(Json.ItemByName(TSmOrderDtlModel.cCdsModelKey).AsString),MemStream);
        if MemStream.Size>0 then
        begin
          fCdsModel.LoadFromStream(MemStream);
        end;
      end;
      ArrayJson:=Json.ItemByName(TSmOrderDtlModel.cObjItemsKey);
      for ItemJson in ArrayJson do
      begin
        Item:=TSmOrderDtl.Create;
        Item.LoadFromStr(ItemJson.AsString,oError);
        if Add(Item)=EmptyStr then
        begin
          Item.Free;
          Result:=False;
          Exit;
        end;
      end;
    end else begin
      Result:=False;
      Exit;
    end;
  finally
    Json.Free;
    MemStream.Free;
  end;
  Result:=True;
end;

function TSmOrderDtlList.SaveToStr():string;
var
  Key:string;
  Json,ItemJson,ArrayJson:TQJson;
  MemStream:TMemoryStream;
begin
  Result:=EmptyStr;
  Json:=TQJson.Create;
  MemStream:=TMemoryStream.Create;
  try
    Json.Add(TSmOrderDtlModel.cObjNameKey).AsString:=Self.ClassName;
    fCdsModel.SaveToStream(MemStream);
    Json.Add(TSmOrderDtlModel.cCdsModelKey).AsString:=string(TSK0001Comm.MemStreamToBase64Str(MemStream));

    ArrayJson:=Json.Add(TSmOrderDtlModel.cObjItemsKey,jdtArray);
    for Key in fSortKeys do
    begin
      ItemJson:=TQJson.Create;
      if ItemJson.TryParse(Items[Key].SaveToStr()) then
      begin
        ArrayJson.Add(ItemJson);
      end else begin
        ItemJson.Free;
      end;
    end;
    Result:=Json.AsString;
  finally
    Json.Free;
    MemStream.Free;
  end;
end;

function TSmOrderDtlList.FindByKey(const iKey:string):TSmOrderDtl;
var
  Item:TSmOrderDtl;
begin
  if TryGetValue(iKey,Item) then
  begin
    Result:=Item;
  end else begin
    Result:=nil;
  end;
end;

function TSmOrderDtlList.IsExist(iKey:string):Boolean;
var
  Item:TSmOrderDtl;
begin
  Result:= TryGetValue(iKey,Item);
end;

function TSmOrderDtlList.Add(const iItem:TSmOrderDtl):string;
begin
  if iItem.ObjGUID<>EmptyStr then
  begin
    inherited Add(iItem.ObjGUID,iItem);
    Result:=iItem.ObjGUID;
    fSortKeys.Add(iItem.ObjGUID);
  end else begin
    Result:=EmptyStr;
  end;
end;

function TSmOrderDtlList.Delete(const iKey:string):Boolean;
var
  Ops:Integer;
begin
  if ContainsKey(iKey) then
  begin
    Remove(iKey).Free;
    Ops:=fSortKeys.IndexOf(iKey);
    if Ops<>-1 then
    begin
      fSortKeys.Delete(Ops);
    end;
    Result:=True;
  end else begin
    Result:=False;
  end;
end;

function TSmOrderDtlList.Remove(const iKey:string):TSmOrderDtl;
var
  Ops:Integer;
begin
  if ContainsKey(iKey) then
  begin
    Result:=Items[iKey];
    Ops:=fSortKeys.IndexOf(iKey);
    if Ops<>-1 then
    begin
      fSortKeys.Delete(Ops);
    end;
    inherited Remove(iKey);
  end else begin
    Result:=nil;
  end;
end;

procedure TSmOrderDtlList.Clear;
var
  Key:string;
begin
  for Key in Keys do
  begin
    if Items[Key]<>nil then
    begin
      Items[Key].Free;
    end;
  end;
  fSortKeys.Clear;
  inherited Clear;
end;

end.
